﻿// -------------------------------------------------------------------------
//    @FileName         :    NFSnsFriendPart.cpp
//    @Author           :    gaoyi
//    @Date             :    2025-03-31
//    @Email			:    445267987@qq.com
//    @Module           :    NFSnsFriendPart
//
// -------------------------------------------------------------------------

#include "NFSnsFriendPart.h"

#include <NFSnsFriendUtil.h>

#include "proto_db.pb.h"

#define FRIEND_MAX_COUNT	100

NFSnsFriendPart::NFSnsFriendPart()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFSnsFriendPart::~NFSnsFriendPart()
{
}

int NFSnsFriendPart::CreateInit()
{
    return 0;
}

int NFSnsFriendPart::ResumeInit()
{
    return 0;
}

int NFSnsFriendPart::UnInit()
{
    return 0;
}

int NFSnsFriendPart::LoadFromDb(const proto_ff::tbSnsRoleDetail* pDbData)
{
    CHECK_NULL(0, pDbData);
    m_friend.FromPb(pDbData->friendinfo());
    return 0;
}

int NFSnsFriendPart::SaveDb(proto_ff::tbSnsRoleDetail* pDbData)
{
    CHECK_NULL(0, pDbData);
    m_friend.ToPb(pDbData->mutable_friendinfo());
    return 0;
}

int NFSnsFriendPart::MakeDataCs(proto_ff::MyFriendInfo* pInfo)
{
    CHECK_NULL(0, pInfo);
    m_friend.ToPb(pInfo);
    return 0;
}

FriendInfo* NFSnsFriendPart::GetBlack(uint64_t roleId)
{
    return const_cast<FriendInfo*>(static_cast<const NFSnsFriendPart*>(this)->GetBlack(roleId));
}

FriendInfo* NFSnsFriendPart::GetFriend(uint64_t roleId)
{
    return const_cast<FriendInfo*>(static_cast<const NFSnsFriendPart*>(this)->GetFriend(roleId));
}

const FriendInfo* NFSnsFriendPart::GetBlack(uint64_t roleId) const
{
    auto iter = m_friend.black.find(roleId);
    if (iter != m_friend.black.end())
    {
        return &iter->second;
    }
    return nullptr;
}

const FriendInfo* NFSnsFriendPart::GetFriend(uint64_t roleId) const
{
    auto iter = m_friend.myfriend.find(roleId);
    if (iter == m_friend.myfriend.end())
    {
        return &iter->second;
    }
    return nullptr;
}

IMOtherList* NFSnsFriendPart::GetOther(uint64_t roleId)
{
    return const_cast<IMOtherList*>(static_cast<const NFSnsFriendPart*>(this)->GetOther(roleId));
}

const IMOtherList* NFSnsFriendPart::GetOther(uint64_t roleId) const
{
    auto iter = m_friend.other.find(roleId);
    if (iter == m_friend.other.end())
    {
        return &iter->second;
    }
    return nullptr;
}

FriendDayDegree* NFSnsFriendPart::GetFriendDayDegree(uint64_t roleId)
{
    return const_cast<FriendDayDegree*>(static_cast<const NFSnsFriendPart*>(this)->GetFriendDayDegree(roleId));
}

const FriendDayDegree* NFSnsFriendPart::GetFriendDayDegree(uint64_t roleId) const
{
    auto iter = m_friend.day_degree.find(roleId);
    if (iter == m_friend.day_degree.end())
    {
        return &iter->second;
    }
    return nullptr;
}

void NFSnsFriendPart::OtherDelMeFriend(uint64_t roleId)
{
    auto pOther = GetOther(roleId);
    if (pOther)
    {
        m_friend.other.erase(roleId);
        DeleteFriendDayDegree(roleId);
        MarkDirty();
    }
}

void NFSnsFriendPart::AddFriendDayDegree(uint64_t roleId, int degree)
{
    FriendDayDegree* pDayDegree = GetFriendDayDegree(roleId);
    if (!pDayDegree)
    {
        if (m_friend.day_degree.size() < m_friend.day_degree.max_size())
        {
            pDayDegree = &m_friend.day_degree[roleId];
            pDayDegree->role_id = roleId;
            pDayDegree->friend_degree = 0;
        }
    }

    if (pDayDegree)
    {
        pDayDegree->friend_degree += degree;
        MarkDirty();
    }
}

void NFSnsFriendPart::DeleteFriendDayDegree(uint64_t roleId)
{
    auto pDayDegree = GetFriendDayDegree(roleId);
    if (pDayDegree)
    {
        m_friend.day_degree.erase(roleId);
        MarkDirty();
    }
}

bool NFSnsFriendPart::CheckFriendFull()
{
    return m_friend.myfriend.size() >= m_friend.myfriend.max_size();
}

bool NFSnsFriendPart::CheckSimpleFriendFull()
{
    return m_friend.myfriend.size() >= FRIEND_MAX_COUNT;
}

bool NFSnsFriendPart::CheckBlackFull()
{
    return m_friend.black.size() >= m_friend.black.max_size();
}

FriendInfo* NFSnsFriendPart::AddFriend(uint64_t roleId, bool bIsSnsFriend)
{
    CHECK_EXPR(m_friend.myfriend.size() < m_friend.myfriend.max_size(), nullptr, "myfriend full, roleId:{}", roleId);
    CHECK_EXPR(m_friend.myfriend.find(roleId) == m_friend.myfriend.end(), nullptr, "roleId exist, roleId:{}", roleId);

    auto pAddFriend = &m_friend.myfriend[roleId];
    pAddFriend->role_id = roleId;
    pAddFriend->friend_time = NF_ADJUST_TIMENOW();
    pAddFriend->is_sns_friend = bIsSnsFriend;
    MarkDirty();
    return pAddFriend;
}

FriendInfo* NFSnsFriendPart::AddBlack(uint64_t roleId)
{
    CHECK_EXPR(m_friend.black.size() < m_friend.black.max_size(), nullptr, "black full, roleId:{}", roleId);
    CHECK_EXPR(m_friend.black.find(roleId) == m_friend.black.end(), nullptr, "roleId exist, roleId:{}", roleId);

    auto pAddFriend = &m_friend.myfriend[roleId];
    pAddFriend->role_id = roleId;
    pAddFriend->friend_time = NF_ADJUST_TIMENOW();
    MarkDirty();
    return pAddFriend;
}

IMOtherList* NFSnsFriendPart::OtherAddMeFriend(uint64_t roleId, bool isFriend)
{
    auto pOther = GetOther(roleId);
    if (pOther)
    {
        pOther->is_friend = isFriend;
        return pOther;
    }

    if (m_friend.other.size() >= m_friend.other.max_size())
    {
        // 查找加了时间最久，而且好友度最低的进行覆盖
        for (auto iter = m_friend.other.list_begin(); iter != m_friend.other.list_end(); ++iter)
        {
            if (!GetFriend(iter->second.role_id))
            {
                m_friend.other.erase(iter->first);
                break;
            }
        }
    }

    // 删除最先加入的，链表头
    if (m_friend.other.size() >= m_friend.other.max_size())
    {
        auto iter = m_friend.other.list_begin();
        NF_ASSERT(iter != m_friend.other.list_end());
        m_friend.other.erase(iter->first);
    }

    pOther = &m_friend.other[roleId];
    pOther->role_id = roleId;
    pOther->is_friend = isFriend;
    return pOther;
}

void NFSnsFriendPart::DelFriend(uint64_t roleId)
{
    auto iter = m_friend.myfriend.find(roleId);
    if (iter != m_friend.myfriend.end())
    {
        m_friend.myfriend.erase(iter);
        MarkDirty();
    }
}

void NFSnsFriendPart::DelBlack(uint64_t roleId)
{
    auto iter = m_friend.black.find(roleId);
    if (iter != m_friend.black.end())
    {
        m_friend.black.erase(iter);
        MarkDirty();
    }
}

int NFSnsFriendPart::OnLogin()
{
    NFSnsFriendUtil::OnRoleLogin(GetRoleDetail());
    return 0;
}

